home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cocktail
/
cg.lha
/
cg
/
src
/
GramYacc.mi
< prev
next >
Wrap
Text File
|
1992-11-24
|
15KB
|
759 lines
IMPLEMENTATION MODULE GramYacc;
IMPORT SYSTEM, System, IO, Tree;
(* line 5 "" *)
FROM IO IMPORT WriteS, WriteNl;
FROM StringMem IMPORT WriteString;
FROM Idents IMPORT NoIdent, tIdent;
FROM Texts IMPORT WriteText;
FROM Sets IMPORT IsElement, Include;
FROM TreeC2 IMPORT TreeIO;
FROM Tree IMPORT
NoTree , tTree , Input , Reverse ,
Class , NoClass , Child , Attribute ,
ActionPart , HasSelector , HasAttributes , NoCodeAttr ,
Referenced , Options , TreeRoot , QueryTree ,
ClassCount , iNoTree , itTree , iModule ,
f , WI, WN , ForallClasses , ForallAttributes,
Nonterminal , Terminal , IdentifyAttribute,
Generated , String ;
IMPORT Strings;
VAR Node ,
ActClass ,
TheClass ,
TheAttr : tTree;
ActActionIndex ,
PrevActionIndex : SHORTCARD;
IsImplicit : BOOLEAN;
PROCEDURE GetBaseClass (Class: tTree): tTree;
BEGIN
WHILE Class^.Class.BaseClass^.Kind # NoClass DO
Class := Class^.Class.BaseClass;
END;
RETURN Class;
END GetBaseClass;
PROCEDURE IsLast (Class, Action: tTree): BOOLEAN;
VAR Found, Last: BOOLEAN;
BEGIN
IsLast2 (Class, Action, Found, Last);
RETURN Last;
END IsLast;
PROCEDURE IsLast2 (t, Action: tTree; VAR pFound, pLast: BOOLEAN);
VAR Found, Last: BOOLEAN;
BEGIN
CASE t^.Kind OF
| Class:
IsLast2 (t^.Class.Attributes, Action, pFound, pLast);
IF pFound OR NOT pLast THEN RETURN; END;
IsLast2 (t^.Class.BaseClass, Action, pFound, pLast);
| Child:
IsLast2 (t^.Child.Next, Action, Found, Last);
pFound := Found;
IF Found THEN
pLast := Last;
ELSE
pLast := FALSE;
END;
| Attribute:
IsLast2 (t^.Attribute.Next, Action, pFound, pLast);
| ActionPart:
IsLast2 (t^.ActionPart.Next, Action, Found, Last);
pFound := Found OR (Action = t);
IF Found THEN
pLast := Last;
ELSE
pLast := Last AND (Action = t);
END;
ELSE
pFound := FALSE;
pLast := TRUE;
END;
END IsLast2;
PROCEDURE yyAbort (yyFunction: ARRAY OF CHAR);
BEGIN
IO.WriteS (IO.StdError, 'Error: module GramYacc, routine ');
IO.WriteS (IO.StdError, yyFunction);
IO.WriteS (IO.StdError, ' failed');
IO.WriteNl (IO.StdError);
Exit;
END yyAbort;
PROCEDURE yyIsEqual (yya, yyb: ARRAY OF SYSTEM.BYTE): BOOLEAN;
VAR yyi : INTEGER;
BEGIN
FOR yyi := 0 TO INTEGER (HIGH (yya)) DO
IF yya [yyi] # yyb [yyi] THEN RETURN FALSE; END;
END;
RETURN TRUE;
END yyIsEqual;
PROCEDURE ParsSpec (t: Tree.tTree);
VAR yyTempo: RECORD CASE : INTEGER OF
END; END;
BEGIN
IF t = Tree.NoTree THEN RETURN; END;
IF (t^.Kind = Tree.Ag) THEN
(* line 84 "" *)
WITH t^.Ag DO
(* line 84 "" *)
WriteS (f, "%{"); WriteNl (f);
WriteS (f, '# include "Scanner.h"'); WriteNl (f);
WriteS (f, "/* EXPORT */"); WriteNl (f);
WriteText (f, ParserCodes^.Codes.Export);
Node := Modules;
WHILE Node^.Kind = Tree.Module DO
WriteText (f, Node^.Module.ParserCodes^.Codes.Export);
Node := Node^.Module.Next;
END;
WriteS (f, "/* GLOBAL */"); WriteNl (f);
WriteText (f, ParserCodes^.Codes.Global);
Node := Modules;
WHILE Node^.Kind = Tree.Module DO
WriteText (f, Node^.Module.ParserCodes^.Codes.Global);
Node := Node^.Module.Next;
END;
WriteS (f, "/* LOCAL */"); WriteNl (f);
WriteText (f, ParserCodes^.Codes.Local);
Node := Modules;
WHILE Node^.Kind = Tree.Module DO
WriteText (f, Node^.Module.ParserCodes^.Codes.Local);
Node := Node^.Module.Next;
END;
WriteNl (f);
WriteS (f, "void BeginParser ()"); WriteNl (f);
WriteS (f, "{"); WriteNl (f);
WriteText (f, ParserCodes^.Codes.Begin);
Node := Modules;
WHILE Node^.Kind = Tree.Module DO
WriteText (f, Node^.Module.ParserCodes^.Codes.Begin);
Node := Node^.Module.Next;
END;
WriteS (f, "}"); WriteNl (f);
WriteNl (f);
WriteS (f, "void CloseParser ()"); WriteNl (f);
WriteS (f, "{"); WriteNl (f);
WriteText (f, ParserCodes^.Codes.Close);
Node := Modules;
WHILE Node^.Kind = Tree.Module DO
WriteText (f, Node^.Module.ParserCodes^.Codes.Close);
Node := Node^.Module.Next;
END;
WriteS (f, "}"); WriteNl (f);
WriteNl (f);
ParsVariant (Classes);
WriteS (f, "%}"); WriteNl (f);
WriteNl (f);
WriteS (f, "%union {"); WriteNl (f);
WriteS (f, " tScanAttribute Scan;"); WriteNl (f);
Node := Classes;
WHILE Node^.Kind = Class DO
WITH Node^.Class DO
IF {Nonterminal, Referenced, HasAttributes} <= Properties THEN
IF (String IN Properties) AND NOT (HasSelector IN Properties) THEN
WriteS (f, " yy"); WN (Name); WriteS (f, " /* "); WI (Name); WriteS (f, " */ yy"); WN (Name); WriteS (f, ";"); WriteNl (f);
ELSE
WriteS (f, " yy"); WI (Selector); WriteS (f, " "); WI (Selector); WriteS (f, ";"); WriteNl (f);
END;
END;
Node := Next;
END;
END;
WriteS (f, "}"); WriteNl (f);
WriteNl (f);
WriteS (f, "%token"); WriteNl (f);
ForallClasses (Classes, Token);
WriteNl (f);
PrecDefs (Precs);
WriteNl (f);
WriteS (f, "%%"); WriteNl (f);
WriteNl (f);
ForallClasses (Classes, ParsSpec);
;
RETURN;
END;
END;
IF (t^.Kind = Tree.Class) THEN
(* line 158 "" *)
WITH t^.Class DO
(* line 158 "" *)
IF {Nonterminal, Referenced} <= Properties THEN
TheClass := t;
Grammar (t);
END;
;
RETURN;
END;
END;
END ParsSpec;
PROCEDURE ParsVariant (t: Tree.tTree);
VAR yyTempo: RECORD CASE : INTEGER OF
END; END;
BEGIN
IF t = Tree.NoTree THEN RETURN; END;
IF (t^.Kind = Tree.Class) THEN
(* line 168 "" *)
WITH t^.Class DO
(* line 168 "" *)
IF {Nonterminal, Referenced, HasAttributes} <= Properties THEN
WriteS (f, "typedef struct { ");
ForallAttributes (Attributes, RecordField);
GenExt (Extensions);
IF (String IN Properties) AND NOT (HasSelector IN Properties) THEN
WriteS (f, "} /* "); WI (Name); WriteS (f, " */ yy"); WN (Name); WriteS (f, ";"); WriteNl (f);
ELSE
WriteS (f, "} yy"); WI (Selector); WriteS (f, ";"); WriteNl (f);
END;
END;
ParsVariant (Next);
;
RETURN;
END;
END;
END ParsVariant;
PROCEDURE GenExt (t: Tree.tTree);
VAR yyTempo: RECORD CASE : INTEGER OF
END; END;
BEGIN
IF t = Tree.NoTree THEN RETURN; END;
IF (t^.Kind = Tree.Class) THEN
(* line 185 "" *)
WITH t^.Class DO
(* line 185 "" *)
ForallAttributes (Attributes, RecordField);
GenExt (Extensions);
GenExt (Next);
;
RETURN;
END;
END;
END GenExt;
PROCEDURE Token (t: Tree.tTree);
VAR yyTempo: RECORD CASE : INTEGER OF
END; END;
BEGIN
IF t = Tree.NoTree THEN RETURN; END;
IF (t^.Kind = Tree.Class) THEN
(* line 194 "" *)
WITH t^.Class DO
(* line 194 "" *)
IF {Terminal, Referenced} <= Properties THEN
WriteS (f, " "); WI (Name); WriteS (f, " "); WN (Code); WriteNl (f);
END;
;
RETURN;
END;
END;
END Token;
PROCEDURE RecordField (t: Tree.tTree);
VAR yyTempo: RECORD CASE : INTEGER OF
END; END;
BEGIN
IF t = Tree.NoTree THEN RETURN; END;
IF (t^.Kind = Tree.Attribute) THEN
(* line 203 "" *)
WITH t^.Attribute DO
(* line 203 "" *)
IF (NoCodeAttr * Properties) = {} THEN
WI (Type); WriteS (f, " "); WI (Name); WriteS (f, "; ");
END;
;
RETURN;
END;
END;
END RecordField;
PROCEDURE PrecDefs (t: Tree.tTree);
VAR yyTempo: RECORD CASE : INTEGER OF
END; END;
BEGIN
IF t = Tree.NoTree THEN RETURN; END;
IF (t^.Kind = Tree.LeftAssoc) THEN
(* line 212 "" *)
WITH t^.LeftAssoc DO
(* line 212 "" *)
WriteS (f, "%left "); PrecDefs (Names); WriteNl (f);
PrecDefs (Next);
;
RETURN;
END;
END;
IF (t^.Kind = Tree.RightAssoc) THEN
(* line 216 "" *)
WITH t^.RightAssoc DO
(* line 216 "" *)
WriteS (f, "%right"); PrecDefs (Names); WriteNl (f);
PrecDefs (Next);
;
RETURN;
END;
END;
IF (t^.Kind = Tree.NonAssoc) THEN
(* line 220 "" *)
WITH t^.NonAssoc DO
(* line 220 "" *)
WriteS (f, "%none "); PrecDefs (Names); WriteNl (f);
PrecDefs (Next);
;
RETURN;
END;
END;
IF (t^.Kind = Tree.Name) THEN
(* line 224 "" *)
WITH t^.Name DO
(* line 224 "" *)
WriteS (f, " "); WI (Name);
PrecDefs (Next);
;
RETURN;
END;
END;
END PrecDefs;
PROCEDURE Grammar (t: Tree.tTree);
VAR yyTempo: RECORD CASE : INTEGER OF
END; END;
BEGIN
IF t = Tree.NoTree THEN RETURN; END;
IF (t^.Kind = Tree.Class) THEN
(* line 232 "" *)
WITH t^.Class DO
(* line 232 "" *)
IF Extensions^.Kind = Tree.NoClass THEN (* Low ? *)
WITH TheClass^.Class DO
IF String IN Properties THEN WriteS (f, "yy"); WN (Name); ELSE WI (Name); END;
END;
WriteS (f, " : ");
ActClass := t;
PrevActionIndex := 0;
IsImplicit := FALSE;
ForallAttributes (t, Rule);
IF Prec # NoIdent THEN WriteS (f, "%prec "); WI (Prec); WriteS (f, " "); END;
WriteS (f, ";"); WriteNl (f);
PrevActionIndex := 0;
IsImplicit := TRUE;
ForallAttributes (t, Implicit);
ELSE
Rule (Extensions);
END;
;
RETURN;
END;
END;
END Grammar;
PROCEDURE Rule (t: Tree.tTree);
VAR yyTempo: RECORD CASE : INTEGER OF
END; END;
BEGIN
IF t = Tree.NoTree THEN RETURN; END;
CASE t^.Kind OF
| Tree.Class:
(* line 255 "" *)
WITH t^.Class DO
(* line 255 "" *)
Grammar (t);
Rule (Next);
;
RETURN;
END;
| Tree.Child:
(* line 259 "" *)
WITH t^.Child DO
(* line 259 "" *)
IF {String, Nonterminal} <= Class^.Class.Properties THEN WriteS (f, "yy"); WN (Type); ELSE WI (Type); END; WriteS (f, " ");
;
RETURN;
END;
| Tree.ActionPart:
(* line 262 "" *)
WITH t^.ActionPart DO
(* line 262 "" *)
IF NOT IsElement (ORD ('v'), Options) THEN
IF IsLast (ActClass, t) THEN
WriteS (f, "{");
IF PrevActionIndex # 0 THEN
Node := GetBaseClass (TheClass);
WITH Node^.Class DO
WriteS (f, " $$.");
IF String IN Properties THEN WriteS (f, "yy"); WN (Name); ELSE WI (Name); END;
WriteS (f, " = $"); WN (PrevActionIndex); WriteS (f, ".");
IF String IN Properties THEN WriteS (f, "yy"); WN (Name); ELSE WI (Name); END;
WriteS (f, ";"); WriteNl (f);
END;
END;
Rule (Actions);
WriteS (f, "} ");
ELSE
WriteS (f, "xx"); WN (Name); WriteS (f, " ");
END;
PrevActionIndex := ParsIndex;
END;
;
RETURN;
END;
| Tree.Assign:
(* line 284 "" *)
WITH t^.Assign DO
(* line 284 "" *)
Rule (Results); WriteS (f, "="); Rule (Arguments); WriteS (f, ";"); WriteNl (f);
Rule (Next);
;
RETURN;
END;
| Tree.Copy:
(* line 288 "" *)
WITH t^.Copy DO
(* line 288 "" *)
Rule (Results); WriteS (f, " = "); Rule (Arguments); WriteS (f, ";"); WriteNl (f);
Rule (Next);
;
RETURN;
END;
| Tree.TargetCode:
(* line 292 "" *)
WITH t^.TargetCode DO
(* line 292 "" *)
Rule (Code); WriteS (f, ";"); WriteNl (f);
Rule (Next);
;
RETURN;
END;
| Tree.Order:
(* line 296 "" *)
WITH t^.Order DO
(* line 296 "" *)
Rule (Next);
;
RETURN;
END;
| Tree.Check:
(* line 299 "" *)
WITH t^.Check DO
(* line 299 "" *)
IF Statement # NoTree THEN
IF Condition # NoTree THEN
WriteS (f, "if ("); Rule (Condition); WriteS (f, ") ; else { "); Rule (Statement); WriteS (f, " }"); WriteNl (f);
ELSE
Rule (Statement);
END;
END;
Rule (Next);
;
RETURN;
END;
| Tree.Designator:
(* line 309 "" *)
WITH t^.Designator DO
(* line 309 "" *)
TheAttr := IdentifyAttribute (ActClass, Selector);
IF TheAttr # NoTree THEN
Node := TheAttr^.Child.Class;
IF Node # NoTree THEN
WriteS (f, "$");
IF NOT IsImplicit THEN
WN (TheAttr^.Child.ParsIndex);
ELSE
WN (SHORTINT (TheAttr^.Child.ParsIndex + 1 - ActActionIndex));
END;
IF Nonterminal IN Node^.Class.Properties THEN (* nonterminal *)
Node := GetBaseClass (Node);
IF (String IN Node^.Class.Properties) AND NOT (HasSelector IN Node^.Class.Properties) THEN
WriteS (f, ".yy"); WN (Node^.Class.Name);
ELSE
WriteS (f, "."); WI (Node^.Class.Name);
END;
ELSE (* terminal *)
IF (String IN Node^.Class.Properties) AND NOT (HasSelector IN Node^.Class.Properties) THEN
WriteS (f, ".Scan.yy"); WN (Node^.Class.Code);
ELSE
WriteS (f, ".Scan."); WI (Node^.Class.Selector);
END;
END;
WriteS (f, "."); WI (Attribute);
ELSE
WI (Selector); WriteS (f, ":"); WI (Attribute);
END;
ELSE
WI (Selector); WriteS (f, ":"); WI (Attribute);
END;
Rule (Next);
;
RETURN;
END;
| Tree.Ident:
(* line 343 "" *)
WITH t^.Ident DO
(* line 343 "" *)
TheAttr := IdentifyAttribute (ActClass, Attribute);
Node := GetBaseClass (TheClass);
IF TheAttr # NoTree THEN
IF (String IN Node^.Class.Properties) AND NOT (HasSelector IN Node^.Class.Properties) THEN
WriteS (f, "$$.yy"); WN (Node^.Class.Name); WriteS (f, "."); WI (Attribute);
ELSE
WriteS (f, "$$."); WI (Node^.Class.Name); WriteS (f, "."); WI (Attribute);
END;
ELSE
WI (Attribute);
END;
Rule (Next);
;
RETURN;
END;
| Tree.Any:
(* line 357 "" *)
WITH t^.Any DO
(* line 357 "" *)
WriteString (f, Code);
Rule (Next);
;
RETURN;
END;
| Tree.Anys:
(* line 361 "" *)
WITH t^.Anys DO
(* line 361 "" *)
Rule (Layouts);
Rule (Next);
;
RETURN;
END;
| Tree.LayoutAny:
(* line 365 "" *)
WITH t^.LayoutAny DO
(* line 365 "" *)
WriteString (f, Code);
Rule (Next);
;
RETURN;
END;
ELSE END;
END Rule;
PROCEDURE Implicit (t: Tree.tTree);
VAR yyTempo: RECORD CASE : INTEGER OF
END; END;
BEGIN
IF t = Tree.NoTree THEN RETURN; END;
IF (t^.Kind = Tree.ActionPart) THEN
(* line 373 "" *)
WITH t^.ActionPart DO
(* line 373 "" *)
IF NOT (Generated IN Properties) AND NOT IsLast (ActClass, t) THEN
INCL (Properties, Generated);
ActActionIndex := ParsIndex;
WriteS (f, "xx"); WN (Name); WriteS (f, " : {");
IF PrevActionIndex # 0 THEN
Node := GetBaseClass (TheClass);
WITH Node^.Class DO
WriteS (f, " $$.");
IF String IN Properties THEN WriteS (f, "yy"); WN (Name); ELSE WI (Name); END;
WriteS (f, " = $"); WN (SHORTINT (PrevActionIndex + 1 - ActActionIndex)); WriteS (f, ".");
IF String IN Properties THEN WriteS (f, "yy"); WN (Name); ELSE WI (Name); END;
WriteS (f, ";"); WriteNl (f);
END;
END;
Rule (Actions);
WriteS (f, "} ."); WriteNl (f);
END;
PrevActionIndex := ParsIndex;
;
RETURN;
END;
END;
END Implicit;
PROCEDURE BeginGramYacc;
BEGIN
END BeginGramYacc;
PROCEDURE CloseGramYacc;
BEGIN
END CloseGramYacc;
PROCEDURE yyExit;
BEGIN
IO.CloseIO; System.Exit (1);
END yyExit;
BEGIN
yyf := IO.StdOutput;
Exit := yyExit;
BeginGramYacc;
END GramYacc.